﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using YasharEl.Infrastructure.ApplicationModel.Bootstrap.Extensibility;
using YasharEl.Infrastructure.ApplicationModel.Bootstrap.Execution;
using YasharEl.Infrastructure.ObjectFactory;

namespace YasharEl.Infrastructure.ApplicationModel.Bootstrap.Reporting
{
    /// <summary>
    /// The reporting context contains all necessary information about the bootstrapping process.
    /// </summary>
    public class ReportingContext : IReportingContext
    {
        private readonly Collection<IBootstrappingExtensionContext> extensions;

        /// <summary>
        /// Initializes a new instance of the <see cref="ReportingContext"/> class.
        /// </summary>
        public ReportingContext()
        {
            this.extensions = new Collection<IBootstrappingExtensionContext>();
        }

        public IExecutionContext Run { get; private set; }

        public IExecutionContext Shutdown { get; private set; }

        public IExecutionContext Configure
        {
            get;
            private set;
        }

        public IExecutionContext CreateConfigureExecutionContext(IDescribable describable, BaseDependencyContainer container)
        {
            this.Configure = this.CreateExecutionContextCore(describable,container);
            return this.Configure;
        }

        /// <inheritdoc />
        public IEnumerable<IBootstrappingExtensionContext> Extensions
        {
            get
            {
                return this.extensions;
            }
        }

        /// <inheritdoc />
        public IExecutionContext CreateRunExecutionContext(IDescribable describable, BaseDependencyContainer container)
        {
            this.Run = this.CreateExecutionContextCore(describable,container);
            return this.Run;
        }

        /// <inheritdoc />
        public IExecutionContext CreateShutdownExecutionContext(IDescribable describable, BaseDependencyContainer container)
        {
            this.Shutdown = this.CreateExecutionContextCore(describable, container);
            return this.Shutdown;
        }

        /// <inheritdoc />
        public IBootstrappingExtensionContext CreateExtensionContext(IDescribable describable)
        {
            var extensionInfo = this.CreateExtensionContextCore(describable);

            this.extensions.Add(extensionInfo);

            return extensionInfo;
        }

        /// <summary>
        /// Creates the extension context implementation.
        /// </summary>
        /// <param name="describable">The describable which is passed to the extension context.</param>
        /// <returns>A new instance of the extension context implementation.</returns>
        protected virtual IBootstrappingExtensionContext CreateExtensionContextCore(IDescribable describable)
        {
            return new BootstrappingExtensionContext(describable);
        }

        /// <summary>
        /// Creates the execution context implementation.
        /// </summary>
        /// <param name="describable">The describable which is passed to the execution context.</param>
        /// <returns>A new instance of the execution context implementation.</returns>
        protected virtual IExecutionContext CreateExecutionContextCore(IDescribable describable,BaseDependencyContainer container)
        {
            return new ExecutionContext(describable, container);
        }
    }
}
